package middleware

import (
	"fmt"
	"net/http"
	"strings"
	"sync"
	"time"

	"things_iot_backend/auth"
	"things_iot_backend/database"
	"things_iot_backend/models"

	"github.com/gin-gonic/gin"
)

// AuthMiddleware JWT认证中间件
func AuthMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 获取Authorization头
		authHeader := c.GetHeader("Authorization")
		if authHeader == "" {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code":    401,
				"message": "未授权",
				"data":    nil,
			})
			c.Abort()
			return
		}

		// 提取令牌
		tokenString, err := auth.ExtractTokenFromHeader(authHeader)
		if err != nil {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code":    401,
				"message": "无效的授权头格式",
				"data":    nil,
			})
			c.Abort()
			return
		}

		// 验证令牌
		claims, err := auth.ValidateToken(tokenString)
		if err != nil {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code":    401,
				"message": "无效的令牌",
				"data":    nil,
			})
			c.Abort()
			return
		}

		// 将用户信息存储到上下文中
		c.Set("claims", claims)
		c.Next()
	}
}

// AdminMiddleware 管理员权限中间件
func AdminMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		claims, exists := c.Get("claims")
		if !exists {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code":    401,
				"message": "未授权",
				"data":    nil,
			})
			c.Abort()
			return
		}

		userClaims := claims.(*auth.Claims)
		if !auth.IsSuperAdmin(userClaims) {
			c.JSON(http.StatusForbidden, gin.H{
				"code":    403,
				"message": "权限不足",
				"data":    nil,
			})
			c.Abort()
			return
		}

		c.Next()
	}
}

// CORSMiddleware 跨域中间件
func CORSMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 允许所有来源访问，包括IP地址
		origin := c.Request.Header.Get("Origin")
		if origin != "" {
			c.Writer.Header().Set("Access-Control-Allow-Origin", origin)
		} else {
			c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		}
		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE, PATCH")

		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(204)
			return
		}

		c.Next()
	}
}

// LoggerMiddleware 日志中间件
func LoggerMiddleware() gin.HandlerFunc {
	return gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
		return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
			param.ClientIP,
			param.TimeStamp.Format(time.RFC1123),
			param.Method,
			param.Path,
			param.Request.Proto,
			param.StatusCode,
			param.Latency,
			param.Request.UserAgent(),
			param.ErrorMessage,
		)
	})
}

// RateLimitMiddleware 限流中间件
func RateLimitMiddleware() gin.HandlerFunc {
	// 简单的基于IP的限流
	// 在实际生产环境中，您可能需要使用更复杂的限流方案
	limiter := make(map[string]int)
	var mu sync.Mutex

	return func(c *gin.Context) {
		clientIP := c.ClientIP()

		mu.Lock()
		limiter[clientIP]++
		count := limiter[clientIP]
		mu.Unlock()

		// 每秒清理一次
		go func() {
			time.Sleep(time.Second)
			mu.Lock()
			delete(limiter, clientIP)
			mu.Unlock()
		}()

		if count > 100 { // 限制每秒100个请求
			c.JSON(http.StatusTooManyRequests, gin.H{
				"code":    429,
				"message": "请求过于频繁",
				"data":    nil,
			})
			c.Abort()
			return
		}

		c.Next()
	}
}

// DeviceAccessMiddleware 设备访问权限中间件
func DeviceAccessMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		claims, exists := c.Get("claims")
		if !exists {
			c.JSON(http.StatusUnauthorized, gin.H{
				"code":    401,
				"message": "未授权",
				"data":    nil,
			})
			c.Abort()
			return
		}

		userClaims := claims.(*auth.Claims)
		deviceID := c.Param("device_id")

		// 如果是超级管理员，允许访问所有设备
		if auth.IsSuperAdmin(userClaims) {
			c.Next()
			return
		}

		// 检查用户是否有权访问该设备
		// 这里需要查询数据库验证设备所有权
		// 在实际实现中，您可能需要注入数据库连接
		var device models.Device
		if err := database.DB.Where("device_id = ?", deviceID).First(&device).Error; err != nil {
			c.JSON(http.StatusNotFound, gin.H{
				"code":    404,
				"message": "设备不存在",
				"data":    nil,
			})
			c.Abort()
			return
		}

		if device.UserID != userClaims.UserID {
			c.JSON(http.StatusForbidden, gin.H{
				"code":    403,
				"message": "无权访问该设备",
				"data":    nil,
			})
			c.Abort()
			return
		}

		c.Set("device", device)
		c.Next()
	}
}

// ErrorHandlerMiddleware 错误处理中间件
func ErrorHandlerMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		defer func() {
			if err := recover(); err != nil {
				c.JSON(http.StatusInternalServerError, gin.H{
					"code":    500,
					"message": "服务器内部错误",
					"data":    nil,
				})
				c.Abort()
			}
		}()

		c.Next()

		// 检查是否有错误
		if len(c.Errors) > 0 {
			lastError := c.Errors.Last()
			if lastError != nil {
				// 根据错误类型返回不同的状态码
				switch {
				case strings.Contains(lastError.Error(), "not found"):
					c.JSON(http.StatusNotFound, gin.H{
						"code":    404,
						"message": "资源不存在",
						"data":    nil,
					})
				case strings.Contains(lastError.Error(), "permission") || strings.Contains(lastError.Error(), "forbidden"):
					c.JSON(http.StatusForbidden, gin.H{
						"code":    403,
						"message": "权限不足",
						"data":    nil,
					})
				case strings.Contains(lastError.Error(), "unauthorized"):
					c.JSON(http.StatusUnauthorized, gin.H{
						"code":    401,
						"message": "未授权",
						"data":    nil,
					})
				default:
					c.JSON(http.StatusInternalServerError, gin.H{
						"code":    500,
						"message": "服务器内部错误",
						"data":    nil,
					})
				}
				c.Abort()
			}
		}
	}
}
